package com.example.basecore.command;

import com.example.basecore.dto.Command;
import com.example.basecore.factory.CommandExecutorFactory;
import com.example.basecore.factory.CommandInterceptorFactory;

import java.util.Objects;
import java.util.Set;

/**
 * @author ycd0075
 * @date 2024-01-25 22:11
 */
public class CommandInvocation <R,C extends Command> {

    private final CommandExecutorFactory commandExecutorFactory;
    private final CommandInterceptorFactory commandInterceptorFactory;

    public CommandInvocation(CommandExecutorFactory commandExecutorFactory, CommandInterceptorFactory commandInterceptorFactory) {
        this.commandExecutorFactory = commandExecutorFactory;
        this.commandInterceptorFactory = commandInterceptorFactory;
    }

    /**
     * 命令执行器
     * @param cmd
     * @return
     */
    public R invoke(C cmd) {
        preIntercept(cmd);
        R res = (R)commandExecutorFactory.create(cmd).execute(cmd);
        postIntercept(cmd,res);
        return res;
    }

    private void preIntercept(Command c) {
        if (Objects.isNull(commandInterceptorFactory)) {
            return;
        }
        Set<CommandInterceptor> cmdInterSets =  commandInterceptorFactory.create(c);
        if(Objects.isNull(cmdInterSets) || cmdInterSets.size() == 0){
            return;
        }

        for (CommandInterceptor preInterceptor : cmdInterSets) {
            preInterceptor.preIntercept(c);
        }
    }

    private void postIntercept(Command c,R r) {
        if (Objects.isNull(commandInterceptorFactory)) {
            return;
        }
        Set<CommandInterceptor> cmdInterSets =  commandInterceptorFactory.create(c);
        if(Objects.isNull(cmdInterSets) || cmdInterSets.size() == 0){
            return;
        }

        for (CommandInterceptor postInterceptor : cmdInterSets) {
            postInterceptor.postIntercept(r);
        }
    }
}
